package com.yyfax.pay.depository.service.inner.impl;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.yyfax.commons.json.FastJsonUtil;
import com.yyfax.framework.common.Log;
import com.yyfax.pay.common.enums.FuiouBusiTypeEnum;
import com.yyfax.pay.common.enums.FuiouDepositRspCodeEnum;
import com.yyfax.pay.common.enums.FuiouDepositStateEnum;
import com.yyfax.pay.common.exception.PayExceptionCode;
import com.yyfax.pay.common.model.to.YYPayApiReq2;
import com.yyfax.pay.common.model.vo.BackResultFormVO;
import com.yyfax.pay.common.model.vo.RedirectFormVO;
import com.yyfax.pay.common.util.FuiouIdUtils;
import com.yyfax.pay.depository.dao.FuiouChangePhoneDao;
import com.yyfax.pay.depository.domain.FuiouChangePhone;
import com.yyfax.pay.depository.service.inner.AccountInnerService;
import com.yyfax.pay.depository.service.inner.FuiouDepositCommonService;
import com.yyfax.pay.depository.vo.FuiouChangePhoneVO;
import com.yyfax.pay.order.service.PayCommonService;
import com.yyfax.pay.third.facade.fuioudeposit.FuiouDepositService;
import com.yyfax.pay.third.model.to.fuioudeposit.FuiouChangePhoneBackReq;
import com.yyfax.pay.third.model.to.fuioudeposit.FuiouChangePhoneFormVO;
import com.yyfax.pay.vo.depository.ChangePhoneReq;
import com.yyfax.pay.vo.depository.ChangePhoneRsp;

@Service
public class AccountInnerServiceImpl implements AccountInnerService {
	private Logger logger = LoggerFactory.getLogger(getClass());

	@Resource
	private FuiouIdUtils fuiouIdUtils;

	@Resource
	private FuiouChangePhoneDao fuiouChangePhoneDao;

	@Resource
	private FuiouDepositService fuiouDepositService;

	@Resource
	private PayCommonService payCommonService;

	@Resource
	private FuiouDepositCommonService fuiouDepositCommonService;



	@Override
	public FuiouChangePhoneVO saveChangePhone(String merchantCode, ChangePhoneReq params) {
		final String op = "AccountInnerServiceImpl.saveChangePhone";

		FuiouChangePhone po = new FuiouChangePhone();
		po.setBusiId(fuiouIdUtils.generateBusiId(FuiouBusiTypeEnum.CHANGE_PHONE, merchantCode));
		po.setMerchantCode(merchantCode);
		po.setOrderId(params.getOrderId());
		po.setOrderTime(params.getOrderTime());
		po.setUserId(params.getUserId());
		po.setBackUrl(params.getBackUrl());
		po.setPageBackUrl(params.getPageBackUrl());
		po.setLoginId(params.getLoginId());
		po.setState(FuiouDepositStateEnum.INI.getValue());
		po.setTerminal(params.getTerminal());

		try {
			fuiouChangePhoneDao.insert(po);
		} catch (DuplicateKeyException e) {
			logger.warn(Log.op(op).msg("保持更换手机订单，主键冲突").kv("merchantCode", merchantCode).kv("orderId", params.getOrderId()).toString());
			po = fuiouChangePhoneDao.selectByMerchantCodeAndOrderId(merchantCode, params.getOrderId());
			if (po == null) {
				logger.error(Log.op(op).msg("保存订单信息主键冲突,查询订单的不存在").kv("merchantCode", merchantCode).kv("orderId", params.getOrderId()).toString());
				throw PayExceptionCode.ORDER_NOT_FOUND.exp();
			}
		}

		return FuiouChangePhoneVO.newInstance(po);
	}

	@Override
	public RedirectFormVO<FuiouChangePhoneFormVO> getChangePhoneForm(FuiouChangePhoneVO vo) {
		// 封装富友更换手机网关请求参数
		return fuiouDepositService.getChangePhoneForm(vo.getPo());
	}

	@Override
	public FuiouChangePhoneVO parseChangePhoneBackResult(String merchantCode, FuiouChangePhoneBackReq req) {
		final String op = "AccountInnerServiceImpl.parseChangePhoneBackResult";
		// 解析请求的合法
		boolean isSign = fuiouDepositService.checkSignRspResult(merchantCode, req, req.getSignature());
		if (!isSign) {
			throw PayExceptionCode.ERROR_SIGN_FAIL.exp();
		}

		FuiouChangePhone po = fuiouChangePhoneDao.selectByBusiId(req.getMchnt_txn_ssn());

		if (po == null) {
			logger.error(Log.op(op).msg("更换手机同步结果响应，没有查到相应订单信息").kv("busiId", req.getMchnt_txn_ssn()).toString());
			throw PayExceptionCode.ERROR_ILL_PARAMETER.exp();
		}

		FuiouChangePhoneVO vo = FuiouChangePhoneVO.newInstance(po);

		if (vo.isResult()) {
			// 如果订单已经出结果，则直接返回
			return vo;
		}

		// 更新订单状态
		FuiouDepositStateEnum state = FuiouDepositStateEnum.FAIL;

		int rspCode = PayExceptionCode.ERROR_OPT_FAIL.getCode();
		String rspMsg = req.getResp_desc();
		if (FuiouDepositRspCodeEnum.SUCCESS.isValue(req.getResp_code())) {
			state = FuiouDepositStateEnum.SUCCESS;

			rspCode = PayExceptionCode.SUCCESS.getCode();
			// 更换手机业务不是更换用户的银行预留手机号，所以不做更新手机的动作
			// if (StringUtils.isNotBlank(req.getNew_mobile())) {
			// // 更新用户手机信息
			// userPaymentService.modifyPhone(merchantCode, po.getUserId(), PaymentEnum.FUIOU_DEPOSIT.getValue(), req.getNew_mobile());
			// }
		}

		po.setState(state.getValue());
		po.setNewPhone(req.getNew_mobile());
		po.setRspCode(rspCode);
		po.setRspMsg(rspMsg);

		fuiouChangePhoneDao.updateByBusiId(po);

		// 生成同步结果异步通知
		generateChangePhoneBackTask(po);

		return vo;
	}

	@Override
	public RedirectFormVO<BackResultFormVO> getChangePhoneRouteForm(FuiouChangePhone po) {
		try {
			ChangePhoneRsp params = new ChangePhoneRsp();
			params.setOrderId(po.getOrderId());
			params.setRspCode(po.getRspCode());
			params.setRspMsg(po.getRspMsg());
			params.setNewPhone(po.getNewPhone());

			BackResultFormVO form = new BackResultFormVO();
			form.setMerchantCode(po.getMerchantCode());
			form.setSign(payCommonService.getSign(po.getMerchantCode(), params));

			form.setParams(JSON.toJSONString(params));

			return RedirectFormVO.newInstance(po.getPageBackUrl(), form);
		} catch (Exception e) {
			logger.error(Log.op("AccountInnerServiceImpl.getChangePhoneRouteForm").msg("封装更换手机网关跳转form异常").kv("busiId", po.getBusiId()).toString(),
					e);
			throw PayExceptionCode.SYS_ERROR.exp();
		}

	}

	/**
	 * 生成更换手机同步结果异步通知任务
	 * 
	 * @author buyi
	 * @date 2017-09-19 16:26:19
	 * @since v2.0.0
	 * @param po
	 * @param rspCode
	 * @param rspMsg
	 */
	private void generateChangePhoneBackTask(FuiouChangePhone po) {
		try {
			ChangePhoneRsp params = new ChangePhoneRsp();
			params.setOrderId(po.getOrderId());
			params.setRspCode(po.getRspCode());
			params.setRspMsg(po.getRspMsg());
			params.setNewPhone(po.getNewPhone());

			YYPayApiReq2<ChangePhoneRsp> req = new YYPayApiReq2<>();
			req.setMerchantCode(po.getMerchantCode());
			req.setSign(payCommonService.getSign(po.getMerchantCode(), params));
			req.setParams(params);

			fuiouDepositCommonService.saveNotifyTask(po.getMerchantCode(), po.getOrderId(), po.getBusiId(), FuiouBusiTypeEnum.CHANGE_PHONE,
					po.getBackUrl(), FastJsonUtil.toJson(req), null, null);
		} catch (Exception e) {
			logger.error(Log.op("ChargeInnerServiceImpl.generateNotifyTask").msg("封装异步通知任务异常").kv("FuiouCharge", po).toString(), e);
		}

	}

}
